#include <jni.h>
#include <string>
// 引入 NDK工具链里面的 log 库
#include <android/log.h>
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>

// 创建TAG宏
#define TAG "NDKHeadTest"
// 创建LOGI宏
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)

#include "FaceTracker.h"
#include "ImageCheck.h"

extern "C"
JNIEXPORT jlong JNICALL
Java_com_ndk_head_FaceTracker_nativeCreateObject(JNIEnv *env, jclass clazz, jstring model_) {
    // 转换人脸训练模型数据为char *
    const char *model = env->GetStringUTFChars(model_, 0);
    FaceTracker *tracker = new FaceTracker(model);
    env->ReleaseStringUTFChars(model_, model);
    // 返回tracker地址给Java层
    return (jlong) tracker;
}

extern "C"
JNIEXPORT void JNICALL
Java_com_ndk_head_FaceTracker_nativeStart(JNIEnv *env, jclass clazz, jlong thiz) {
    LOGI("nativeStart:%d\n", 2);
    if (thiz != 0) {
        FaceTracker *tracker = reinterpret_cast<FaceTracker *>(thiz);
        tracker->tracker->run();
    }
}

/**
 * 实例化播放window 关联 surfaceView
 */
extern "C"
JNIEXPORT void JNICALL
Java_com_ndk_head_FaceTracker_nativeSetSurface(JNIEnv *env, jclass clazz, jlong thiz,
                                               jobject surface) {
    if (thiz != 0) {
        FaceTracker *tracker = reinterpret_cast<FaceTracker *>(thiz);
        if (!surface) {
            tracker->setANativeWindow(0);
            return;
        }
        tracker->setANativeWindow(ANativeWindow_fromSurface(env, surface));
    }
}

extern "C"
JNIEXPORT void JNICALL
Java_com_ndk_head_FaceTracker_nativeDetect(JNIEnv *env, jclass clazz, jlong thiz,
                                           jbyteArray inputImage_, jint width, jint height,
                                           jint rotationDegrees) {
    if (thiz == 0) {
        return;
    }
    FaceTracker *tracker = reinterpret_cast<FaceTracker *>(thiz);
    // 将图片数据转化为jbyte
    jbyte *inputImage = env->GetByteArrayElements(inputImage_, 0);
    // 根据I420宽高，设置Mat（OpenCV支持的图片格式）的宽高，并赋值 src
    Mat src(height * 3 / 2, width, CV_8UC1, inputImage);
    // YUV转为RGBA
    cvtColor(src, src, CV_YUV2RGBA_I420);
    // 旋转图片
    if (rotationDegrees == 90) {
        rotate(src, src, ROTATE_90_CLOCKWISE);
    } else if (rotationDegrees == 270) {
        rotate(src, src, ROTATE_90_COUNTERCLOCKWISE);
    }
    Mat gray; // 存储降噪后的图片（灰度图）
    // 灰度化
    cvtColor(src, gray, CV_RGBA2GRAY);
    // 增强对比度
    equalizeHist(gray, gray);
    // 人脸定位
    tracker->tracker->process(gray);

    std::vector<Rect> faces; // 人脸集合
    tracker->tracker->getObjects(faces);

    for (Rect face: faces) {
        // 找到人脸，画红色矩形框
        rectangle(src, face, Scalar(255, 0, 0));
    }

    tracker->draw(src);
    env->ReleaseByteArrayElements(inputImage_, inputImage, 0);
}

extern "C"
JNIEXPORT void JNICALL
Java_com_ndk_head_FaceTracker_nativeStop(JNIEnv *env, jclass clazz, jlong thiz) {
    if (thiz != 0) {
        FaceTracker *tracker = reinterpret_cast<FaceTracker *>(thiz);
        tracker->tracker->stop();
    }
}

extern "C"
JNIEXPORT void JNICALL
Java_com_ndk_head_FaceTracker_nativeDestroyObject(JNIEnv *env, jclass clazz, jlong thiz) {
    if (thiz != 0) {
        FaceTracker *tracker = reinterpret_cast<FaceTracker *>(thiz);
        tracker->tracker->stop();
        delete tracker;
    }
}
extern "C"
JNIEXPORT jlong JNICALL
Java_com_ndk_head_ImageCheck_nativeCreateImageCheck(JNIEnv *env, jclass clazz) {
    ImageCheck *imageCheck = new ImageCheck();
    // 返回imageCheck地址给Java层
    return (jlong) imageCheck;
}
extern "C"
JNIEXPORT jstring JNICALL
Java_com_ndk_head_ImageCheck_nativeDetectImageCheck(JNIEnv *env, jclass clazz, jlong thiz,
                                                    jbyteArray input_image, jint width,
                                                    jint height) {
    LOGI("nativeDetectImageCheck: %d, Height: %d\n", width, height);
    return env->NewStringUTF(
            "[{\"class_name\":\"bag_incline\",\"score\":0.89,\"bbox\":[[0,444],[102,742]]},{\"class_name\":\"bottle_fall\",\"score\":0.9,\"bbox\":[[903,632],[960,719]]},{\"class_name\":\"bag_fall\",\"score\":0.93,\"bbox\":[[181,1194],[376,1280]]},{\"class_name\":\"bag_normal\",\"score\":0.93,\"bbox\":[[798,814],[960,1066]]},{\"class_name\":\"jar_fall\",\"score\":0.93,\"bbox\":[[0,861],[125,1063]]},{\"class_name\":\"bottle_normal\",\"score\":0.94,\"bbox\":[[816,496],[912,726]]},{\"class_name\":\"jar_fall\",\"score\":0.94,\"bbox\":[[0,208],[315,334]]},{\"class_name\":\"bottle_normal\",\"score\":0.95,\"bbox\":[[750,1143],[837,1279]]},{\"class_name\":\"box_fall\",\"score\":0.95,\"bbox\":[[100,602],[423,737]]},{\"class_name\":\"jar_fall\",\"score\":0.95,\"bbox\":[[429,188],[545,322]]},{\"class_name\":\"jar_fall\",\"score\":0.96,\"bbox\":[[566,170],[693,316]]},{\"class_name\":\"jar_fall\",\"score\":0.96,\"bbox\":[[828,150],[958,304]]},{\"class_name\":\"box_normal\",\"score\":0.97,\"bbox\":[[424,544],[756,740]]},{\"class_name\":\"bag_incline\",\"score\":0.97,\"bbox\":[[482,794],[798,1056]]},{\"class_name\":\"jar_normal\",\"score\":0.97,\"bbox\":[[135,801],[333,1069]]}]");
}

extern "C"
JNIEXPORT jstring JNICALL
Java_com_ndk_head_ImageCheck_nativeDetectBitmap(JNIEnv *env, jclass clazz, jlong thiz,
                                                jintArray pixels, jint width, jint height) {
    // 将 jintArray 转换为 C++ 数组
    jint *c_pixels = env->GetIntArrayElements(pixels, NULL);

    // 创建一个 Mat 对象
    cv::Mat mat(height, width, CV_8UC4, (unsigned char *) c_pixels);

    // 在这里可以继续使用 mat 进行图像处理操作
    LOGI("nativeDetectBitmap:Mat宽度：%d, Mat高度：%d\n", mat.cols, mat.rows);
    // 释放数组
    env->ReleaseIntArrayElements(pixels, c_pixels, 0);
    return env->NewStringUTF(
            "[{\"class_name\":\"bag_incline\",\"score\":0.89,\"bbox\":[[0,444],[102,742]]},{\"class_name\":\"bottle_fall\",\"score\":0.9,\"bbox\":[[903,632],[960,719]]},{\"class_name\":\"bag_fall\",\"score\":0.93,\"bbox\":[[181,1194],[376,1280]]},{\"class_name\":\"bag_normal\",\"score\":0.93,\"bbox\":[[798,814],[960,1066]]},{\"class_name\":\"jar_fall\",\"score\":0.93,\"bbox\":[[0,861],[125,1063]]},{\"class_name\":\"bottle_normal\",\"score\":0.94,\"bbox\":[[816,496],[912,726]]},{\"class_name\":\"jar_fall\",\"score\":0.94,\"bbox\":[[0,208],[315,334]]},{\"class_name\":\"bottle_normal\",\"score\":0.95,\"bbox\":[[750,1143],[837,1279]]},{\"class_name\":\"box_fall\",\"score\":0.95,\"bbox\":[[100,602],[423,737]]},{\"class_name\":\"jar_fall\",\"score\":0.95,\"bbox\":[[429,188],[545,322]]},{\"class_name\":\"jar_fall\",\"score\":0.96,\"bbox\":[[566,170],[693,316]]},{\"class_name\":\"jar_fall\",\"score\":0.96,\"bbox\":[[828,150],[958,304]]},{\"class_name\":\"box_normal\",\"score\":0.97,\"bbox\":[[424,544],[756,740]]},{\"class_name\":\"bag_incline\",\"score\":0.97,\"bbox\":[[482,794],[798,1056]]},{\"class_name\":\"jar_normal\",\"score\":0.97,\"bbox\":[[135,801],[333,1069]]}]");
}